package com.cz.video.common.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.cz.video.common.annotation.LegalContent;
import com.cz.video.common.utils.reflect.ReflectUtils;
import com.cz.video.common.utils.spring.SpringUtils;
import com.github.houbb.sensitive.word.bs.SensitiveWordBs;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Set;

/**
 * Validator 校验框架工具
 *
 * @author Lion Li
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ValidatorUtils {

    private static final Validator VALID = SpringUtils.getBean(Validator.class);


    private static final SensitiveWordBs SENSITIVE_WORD_BS = SpringUtils.getBean(SensitiveWordBs.class);

    public static <T> void validate(T object, Class<?>... groups) {
        Set<ConstraintViolation<T>> validate = VALID.validate(object, groups);
        if (!validate.isEmpty()) {
            throw new ConstraintViolationException("参数校验异常", validate);
        }
    }


    @SneakyThrows
    public static <B> boolean validateLegalContent(B bo){
        Field[] fields = ReflectUtils.getFields(bo.getClass());
        for (Field field : fields) {
            //判断是否需要进行内容审核
            if (field.getAnnotation(LegalContent.class)!=null){
                Object value = ReflectUtils.invokeGetter(bo, field.getName());
                if (!isLegal(String.valueOf(value))) {
                    return false;
                }
            }
        }
        return true;
    }


    /**
     * 校验字符串是否合法
     * @param str 待校验的字符串
     * @return true为合法，false为非法
     */
    public static  boolean isLegal(String str){

        return !SENSITIVE_WORD_BS.contains(str);
    }


    /**
     * 查找非法词列表
     * @apiNote 只返回第一个非法字段找到的非法词列表
     * @param target
     * @return 非法词列表
     */
    @SneakyThrows
    public static List<String> findIllegalWords(Object target) {

        Field[] fields = ReflectUtils.getFields(target.getClass());
        for (Field field : fields) {
            //判断是否需要进行内容审核
            if (field.getAnnotation(LegalContent.class)!=null){
                field.setAccessible(true);
                if (ObjectUtil.isNotNull(field.get(target))) {
                    List<String> illegalWords = SENSITIVE_WORD_BS.findAll(field.get(target).toString());
                    if (CollUtil.isNotEmpty(illegalWords))
                        return illegalWords;
                }
            }
        }

        return null;
    }
}
